﻿using System;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;

namespace TcpServer
{
    internal class Program
    {
        // tcp 采用网络流数 字节数据传输
        private static byte[] result = new byte[1024];
        // 设置端口好 8012
        private static int myport = 8012;
        // 声明一个静态全局的套接字连接器
        static Socket serverSocket;
        static void Main(string[] args)
        {
            // 将ip地址字符串转化为ip地址
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            // 多态创建套接字连接对象，指定套接字类型为网络流，协议为tcp
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // Tcp 套接字绑定ip地址和的口号
            serverSocket.Bind(new IPEndPoint(ip, myport));
            // 服务端开始监听
            serverSocket.Listen(100);
            // 创建一个线程扫描所有的客户端连接
            Thread myThread = new Thread(ListenClientConnect);
            myThread.Start();
            Console.ReadLine();
        }

        /// <summary>
        /// 连接多个客户端主机
        /// </summary>
        private static void ListenClientConnect()
        {
            while (true)
            {
                // 要发送的消息
                string sendmsg = "server send message hello";
                // 拿到客户端套接字获取连接对象，这个时候才和客户端建立真正的连接
                Socket clientsocket = serverSocket.Accept();
                // 发送网络流消息给客户端
                clientsocket.Send(Encoding.ASCII.GetBytes(sendmsg));
                // 创建接收消息线程
                Thread receiveThread = new Thread(ReceiveMessage);
                // 接收线程启动传入客户端套接字对象
                receiveThread.Start(clientsocket);
                Console.WriteLine("发送消息:" + sendmsg);
                // 客户端接收网络流之后的状态
                int receiveNum = clientsocket.Receive(result);
                // 关闭连接
                clientsocket.Shutdown(SocketShutdown.Both);
                clientsocket.Close();
            }
        }

        /// <summary>
        /// 接收多个客户端消息
        /// </summary>
        /// <param name="clientSocket"></param>
        private static void ReceiveMessage(object clientSocket)
        {
            // 服务端套接字对象
            Socket socket = (Socket)clientSocket;
            while (true)
            {
                try
                {
                    // 接收客户端消息状态
                    int receiveNumber = socket.Receive(result);
                    Console.WriteLine("接收客户端消息", socket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
                }
                catch (Exception e)
                {
                    // 关闭连接
                    Console.WriteLine(e.Message);
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();
                    break;
                }
            }
        }
    }
}

